﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SampleAppAPI;
using System.Threading;
using System.IO;

namespace SampleApp.RandomDataGenerators
{
    public class OMSOrderDataEventArgs
    {
        public OMSOrderDataEventArgs(OMSOrderData orderData_)
        {
            OrderData = orderData_;
        }
        public OMSOrderData OrderData { get; protected set; }
    }

    public delegate void NewOMSOrderDataHandler(object sender, OMSOrderDataEventArgs e);

    public class OMSOrderDataGenerator
    {
        private Thread _generatorThread;
        private object _syncObj;
        private bool _generateMoreData;
        private List<OMSOrderData> _sampleOrders;

        public readonly int MaxIntervalBetweenData; // interval in millisec

        public event NewOMSOrderDataHandler NewOMSOrderData;

        protected virtual void OnNewOMSOrderData(OMSOrderDataEventArgs e)
        {
            NewOMSOrderDataHandler handler = NewOMSOrderData;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        public OMSOrderDataGenerator(int maxOrdersToGenerate_, int maxIntervalBetweenData_ = 100)
        {
            _syncObj = new object();
            MaxIntervalBetweenData = maxIntervalBetweenData_;
            // Initialize Random DataStore
            Dictionary<string, string> _symbols = (from symbols in File.ReadAllLines(@"Data\Symbols.csv").Skip(1)
                                                   let symInfo = symbols.Split(new char[] { ',' })
                                                   select new { CompanyName = symInfo[0], StockName = symInfo[1] }).ToDictionary(s => s.StockName, s => s.CompanyName);

            Random random = new Random();

            _sampleOrders = new List<OMSOrderData>(maxOrdersToGenerate_);
            for (int i = 0; i < maxOrdersToGenerate_; i++)
            {
                string symbol = _symbols.Keys.Skip(random.Next(_symbols.Count)).First();
                string companyName = _symbols[symbol];
                OMSOrderData newOrder = new OMSOrderData() { Symbol = symbol, CompanyName = companyName, LimitPrice = random.NextDouble() * 1000, OrderID = Guid.NewGuid() };
                _sampleOrders.Add(newOrder);
            }
            _generatorThread = new Thread(new ThreadStart(GenerateData));
            _generatorThread.Name = "OMSOrderDataGenerator Thread";
            _generateMoreData = true;
            _generatorThread.Start();
        }

        public void Start()
        {
            lock (_syncObj)
            {
                _generateMoreData = true;
            }
        }

        public void Stop()
        {
            lock (_syncObj)
            {
                _generateMoreData = false;
            }
        }

        protected void GenerateData()
        {
            bool generateData;
            Random random = new Random();
            do
            {
                OMSOrderData orderData = _sampleOrders[random.Next(_sampleOrders.Count)];
                orderData.LimitPrice = ((random.NextDouble() - 0.5) * 0.1 + 1) * orderData.LimitPrice;

                OnNewOMSOrderData(new OMSOrderDataEventArgs(orderData));
                Thread.Sleep(random.Next(MaxIntervalBetweenData));
                lock (_syncObj)
                {
                    generateData = _generateMoreData;
                }

            } while (generateData);
        }
    }
}
